#!/usr/bin/env ruby
$:.unshift File.join(File.dirname(__FILE__))
require 'cgi'
require 'amarok.rb'
require "rexml/document"
require 'open-uri'
require 'uri'

@playlist = Amarok.new 'playlist'
@script = Amarok.new 'script'
@contextbrowser = Amarok.new 'contextbrowser'

def cleanup()
  puts( "Script was terminated." )
  exit
end

trap( "SIGTERM" ) { cleanup }
trap( "SIGINT" ) { cleanup }

def log msg
  File.open('/tmp/amarokscript.log', 'a'){|f|
    f.write msg.to_s
    f.write "\n"
  }
end

def escape_xml string
  input = string
  input.gsub!("&", "&amp;")
  input.gsub!("<", "&lt;")
  input.gsub!(">", "&gt;")
  input.gsub!("'", "&apos;")
  input.gsub!("\"", "&quot;")
  input
end

MAX_LENGTH = 40
SUFFIX = "..."
def wrap string
  wrapped = string
  if string.length > MAX_LENGTH
    wrapped = string[0..(MAX_LENGTH - SUFFIX.length)] + SUFFIX 
  end
  wrapped
end

def cleanHTML string
  string = string.to_s
  tags = ['script', 'style']
  tags.each {|tag|
    string.gsub! /<#{tag}.+?\/#{tag}>/m, ''
  }
    string.gsub! /<!--.+?-->/m, ''      #comments
    string.gsub! /[ ]*<[^>]*>[ ]*/, ''  #tags
    string = CGI::unescape string
    string.gsub! /&.+?;/, ''            #escape_xmls remaining
    string.gsub! /(\s*\n\s*){3,}/, "\n" #extra carriage returns created by previous steps
    string
end

############################## SCRIPT LOOP ################################
artist = ""
title = ""
loop do
  begin
    message = gets().chomp()
    puts "message: #{message}"
    command = /[A-Za-z]*/.match(message).to_s

    case command
    when "configure"
      msg  = 'This script does not have configuration options.'
      @playlist.popup_message msg

    when "fetchLyrics"
      args = message.split
      if args.length < 3
        @playlist.popup_message "Not enough information in tags to retrieve lyrics"
      end
      artist = CGI::unescape args[1]
      title  = CGI::unescape args[2]
      search_url = "http://www.google.com/search?q=#{CGI::escape artist}%20#{CGI::escape title}%20lyrics"

      response = open(search_url).read
      urls = response.scan(/a href="([^"]*)"/)
      urls.map! {|group| group[0]}
      urls = urls.select {|url| url !~ /google/ and url !~ /youtube/ and url[0..0] != '/'}

      suggestions = ""
      urls.each_with_index {|url, index|
        suggestions += %{<suggestion artist="#{index + 1}" title="#{wrap(escape_xml(url))}" url="#{escape_xml url}" />}
      }

      xml =%{<suggestions page_url="http://google.com">#{suggestions}</suggestions>}
      @contextbrowser.show_lyrics xml

    when "fetchLyricsByUrl"
      args = message.split
      url = args[1]
      response = IO::popen("lynx -dump #{url}", 'r').read
      response = cleanHTML(open(url).read) if response.nil? or response.chomp.empty?
      xml = %{<lyric artist="#{escape_xml artist}" title="#{escape_xml title}" page_url="#{url}">#{escape_xml response}</lyric>}

      @contextbrowser.show_lyrics xml
    end

  rescue
    @playlist.popup_message "There has been a problem with the lyrics script: #{$!}"
  end
end
